#include "stm32.h"

static struct shm_param para;
int fd;
struct msg data[3];

/**
 * @brief 初始化串口连接参数
 *
 * @return int
 */
int serial_init()
{

    fd = open(DEV_PATH, O_RDWR);
    if (fd < 0)
    {
        perror("msg port  open err");
        exit(0);
    }

    struct termios options;
    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    options.c_cflag |= CS8;
    options.c_cflag &= ~CSTOPB;
    options.c_iflag |= IGNPAR;
    options.c_iflag &= ~(ICRNL | IXON);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cc[VMIN] = 100;
    options.c_cc[VTIME] = 1;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &options);
    return 0;
}
/**
 * @brief 解析点表文件
 *
 * @return int
 */
int read_json()
{

    FILE *fp;
    char buf[4096] = {0};
    if ((fp = fopen("/home/yqj/hq_plat/res/node.json", "r")) == NULL)
    {
        printf("read node.json  err!\n");
        return -1;
    }

    int ret = fread(buf, 4096, 1, fp);
    if (ret < 0)
    {
        perror("fread json error\n");
        return -1;
    }
    printf("read buf=%s\n", buf);
    cJSON *root;
    char *str;

    root = cJSON_Parse(buf);

    cJSON *stm32 = cJSON_GetObjectItem(root, "stm32");
    cJSON *array = cJSON_GetObjectItem(stm32, "data");
    cJSON *msg_point;

    str = cJSON_Print(array);
    printf("%s\n", str);
    free(str);
    cJSON *temp;

    for (int i = 0; i < cJSON_GetArraySize(array); i++)
    {
        temp = cJSON_GetArrayItem(array, i);
        msg_point = cJSON_GetObjectItem(temp, "name");
        strcpy(data[i].name, msg_point->valuestring);
        msg_point = cJSON_GetObjectItem(temp, "key");
        data[i].key = msg_point->valueint;
        printf("%s,%d\n", data[i].name, data[i].key);
    }

    cJSON_Delete(root);
    return 0;
}

/**
 * @brief 循环发送的线程
 *
 * @param arg
 * @return void*
 */
void *shmsend(void *arg)
{
    if (serial_init() < 0)
    {
        LOGE("serial init error");
        return NULL;
    }

    char buf[64] = {0};

    int ret = -1;
    ret = shm_init(&para, "shm_stm32", 1024);
    if (ret < 0)
    {
        LOGE("shm init err\n");
        exit(0);
    }
    // int *addr = (int *)shm_getaddr(&para);

    // if (addr == NULL)
    // {
    //     LOGE("shm get err\n");
    //     exit(0);
    // }
    // int str_num = *(addr);
    // UNUSED(str_num);
    // *(addr) = 4;
    // struct std_node *m_led = NULL;
    // struct std_node *m_lig = NULL;
    // struct std_node *m_bat = NULL;
    struct std_node *data_ptr = shm_getaddr(&para);
    // struct std_node *data_ptr = (struct std_node *)(addr + 1);

    // m_led = data_ptr;
    // data_ptr += 1;
    // m_lig = data_ptr;
    // data_ptr += 1;
    // m_bat = data_ptr;

    while (1)
    {

        if (read(fd, buf, sizeof(struct data_node)) < 0)
        {
            perror("shm read port err!\n");
            continue;
        }

        struct data_node *data = (struct data_node *)buf;

        // m_led->new_val.i_val = data->led;

        // m_lig->new_val.i_val = data->light;

        // m_bat->new_val.f_val = data->bat;
        // printf("黄灯状态=%d ,光敏ADC=%d, 电池=%.2f\n", m_led->new_val.i_val, m_lig->new_val.i_val, m_bat->new_val.f_val);
        data_ptr[0].key = 301;
        data_ptr[0].type = 1;
        data_ptr[0].new_val.i_val = data->light;

        data_ptr[1].key = 302;
        data_ptr[1].type = 3;
        data_ptr[1].new_val.f_val = data->bat;

        data_ptr[2].key = 303;
        data_ptr[2].type = 1;
        data_ptr[2].new_val.i_val = data->led;
        printf("黄灯状态=%d ,光敏ADC=%d, 电池=%.2f\n", data_ptr[2].new_val.i_val, data_ptr[0].new_val.i_val, data_ptr[1].new_val.f_val);
        sleep(2);
    }
}
/**
 * @brief 循环从消息队列中读取数据的线程
 *
 * @param arg
 * @return void*
 */
void *msgrecv(void *arg)
{

    cJSON *node_recv_data = NULL;
    cJSON *json_recv = NULL;
    cJSON *node_recv = NULL;
    char recv_buf_tmp[256];
    struct msgbuf recv_buf;

    // struct msgbuf send_buf;
    // send_buf.mtype = 2;
    if (serial_init() < 0)
    {
        LOGE("serial init error");
        return NULL;
    }
    // 判断消息队列存在
    while (msg_queue_msgexist("msg_stm32", 1))
    {
        msg_queue_recv("msg_stm32", &recv_buf, sizeof(recv_buf), 0, 0);
    }
    while (1)
    {
        // 接收上位机指令并控制stm32的状态
        if (msg_queue_recv("msg_stm32", &recv_buf, sizeof(recv_buf), 1, 0) > 0)
        {
            printf("%s\n", recv_buf.mdata);
            strcpy(recv_buf_tmp, recv_buf.mdata);
            json_recv = cJSON_Parse(recv_buf_tmp);
            node_recv = cJSON_GetObjectItem(json_recv, "data");
            if (NULL == node_recv)
            {
                LOGE("json data get error");
            }

            node_recv_data = cJSON_GetObjectItem(node_recv, "key");
            if (303 == atoi(cJSON_Print(node_recv_data)))
            {
                cJSON_AddStringToObject(node_recv, "dev", "light");
            }
            cJSON_DeleteItemFromObject(node_recv, "key"); // 要删除key字符串
            char *str = cJSON_Print(node_recv);
            printf("str=%s\n", str);
            // 将JSON信息通过串口发给stm32
            if (write(fd, str, strlen(str)) < 0)
            {
                perror("write to stm32 error\n");
                return NULL;
            }
            free(str);
            cJSON_Delete(node_recv);
        }
    }
    pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
    pthread_t tid1, tid2;
    read_json();

    if (pthread_create(&tid1, NULL, shmsend, NULL) != 0)
    {
        perror("pthread create err");
        exit(0);
    }
    LOGD("pthread1 create success");
    if (pthread_create(&tid2, NULL, msgrecv, NULL) != 0)
    {
        perror("pthread create err");
        exit(0);
    }
    LOGD("pthread2 create success");
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}
